package cc.sunni;

import cc.sunni.entity.Student;
import cc.sunni.service.AbsCheckStudent;
import cc.sunni.service.impl.StAgeCheck;
import cc.sunni.service.impl.StGenderCheck;
import cc.sunni.service.impl.StNameCheck;
import cc.sunni.service.impl.StNoCheck;

import java.util.ArrayList;
import java.util.List;

/**
 * 责任链模式
 * 可以控制请求的处理的顺序
 * 单一职责原则，可以对发起操作和执行操作的类进行解耦
 * 开闭原则，可不用修改原有的业务代码，新增其他的处理类
 * 不能保证每个处理者者可以执行
 * 效率不是很好，调用时如果不注意会出现各种各样的问题
 * <p>
 * 责任链模式适用的场景
 * 当必须按顺序执行多个处理者时，可以考虑使用责任链模式
 * 如果处理者的顺序及其必须在运行时改变时，可以考虑使用责任链模式
 */
public class Chain {
    /**
     * 构建责任链和调用
     */
    public static AbsCheckStudent getStudentCheck() {
        //校验姓名
        AbsCheckStudent stNameCheck = new StNameCheck();
        //校验年龄
        AbsCheckStudent stAgeCheck = new StAgeCheck();
        //校验性别
        AbsCheckStudent stGenderCheck = new StGenderCheck();
        //校验学号
        AbsCheckStudent stNoCheck = new StNoCheck();

        //设置好责任链的顺序，把校验年龄的子类当作StNameCheck中的下一个处理者
        stNameCheck.setAbsCheckStudent(stAgeCheck);
        //把校验性别的子类当作StAgeCheck中的下一个处理者
        stAgeCheck.setAbsCheckStudent(stGenderCheck);
        //把学生的编号校验放到性别校验的后面
        stGenderCheck.setAbsCheckStudent(stNoCheck);

        return stNameCheck;
    }

    public static void main(String[] args) {
        AbsCheckStudent studentCheck = getStudentCheck();
        List<Student> studentList = getStudents();
        studentCheck.handleCheck(studentList);

        studentList.forEach(System.out::println);
    }

    public static List<Student> getStudents() {
        List<Student> result = new ArrayList<>();
        Student s1 = new Student();
        s1.setAge(12);
        s1.setGender("男");
        s1.setStName("张三");
        s1.setStNo("");

        Student s2 = new Student();
        s2.setAge(12);
        s2.setGender("男1");
        s2.setStName("张三");
        s2.setStNo("123");

        Student s3 = new Student();
        s3.setAge(12);
        s3.setGender("男");
        s3.setStName("张三");
        s3.setStNo("123");

        result.add(s1);
        result.add(s2);
        result.add(s3);
        return result;
    }
}